/**
 * @file drv_timer.c
 * @brief Code for drv_timer driver
 * @author He Shaohua (hsh15529870639@foxmail.com)
 * @date 2024-05-20
 * @version 1.0
 * @copyright Copyright (c) 2024, SNUT-Chaoyue Team
 * ****************************************************************************************************
 * @par Change Log:
 * <table>
 * <tr><th>Date         <th>Version       <th>Author      <th>Description
 * <tr><td>2024-05-20   <td> 1.0          <td>He Shaohua  <td>Creator
 *
 * </table>
 * ==================================----How to use this driver----=====================================
 * [..]
 * @note
 *   -#
 *
 * @warning
 *   -#
 *
 * *****************************************************************************************************
 * @attention
 *
 * This document is required and please understand any bugs that may occur in the document.
 * If you want to modify this file, after the code update is completed, update the version number in time,
 * indicate the update date, and fill in the changes
 * Make sure that the submitted code does not have many bugs.
 *
 * All rights reserved.
 * *****************************************************************************************************
 */

/* Includes ------------------------------------------------------------------*/
#include "drv_timer.h"

/* Private typedef -----------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static uint32_t Timer_CNT = 0;
static uint32_t Timer_CNT_Last = 0;
static uint32_t Timer_CNT_RountCount = 0;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
void MY_TIMER_Update(void)
{
  Timer_CNT++;
}

/**
 * @brief 检查Timer_CNT寄存器是否溢出,并更新Timer_CNT_RountCount
 * @attention 此函数假设两次调用之间的时间间隔不超过一次溢出
 */
static void TIMER_CNT_Update(void)
{
  static volatile uint8_t bit_locker = 0;
  if (!bit_locker)
  {
    bit_locker = 1;
    volatile uint32_t cnt_now = Timer_CNT;
    if (cnt_now < Timer_CNT_Last)
      Timer_CNT_RountCount++;

    Timer_CNT_Last = Timer_CNT;
    bit_locker = 0;
  }
}

void MY_TIMER_Init(void)
{
  Timer_CNT_RountCount = 0;
  TIMER_CNT_Update();
}

float TIMER_GetDeltaT(uint32_t *cnt_last)
{
  volatile uint32_t cnt_now = Timer_CNT;
  float dt = ((uint32_t)(cnt_now - *cnt_last)) / ((float)(1000));
  *cnt_last = cnt_now;
  TIMER_CNT_Update();
  return dt;
}

void TIMER_Delay_s(float Delay)
{
  uint32_t tickstart = Timer_CNT;
  float wait = Delay;

  while ((Timer_CNT - tickstart) < wait * (float)1000)
    ;
}

void TIMER_Delay_ms(uint32_t Delay)
{
  uint32_t tickstart = Timer_CNT;
  uint32_t wait = Delay;

  while ((Timer_CNT - tickstart) < wait)
    ;
}

void TIMER_Delay_us(uint32_t Delay)
{
  for (size_t i = 0; i < Delay; i++)
  {
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
  }
}
/**
 * @}
 */

/**
 * @}
 */

/**
 * @}
 */

/*********************************END OF FILE*********************************/
